'''
    非阻塞型单线程服务器

    设置为非阻塞之后, 进行accept或recv时如果没有新客户端或新收数据时, 则会抛异常
'''

from socket import *
import time

g_socketList = []

def main():
    serverSocket = socket(AF_INET, SOCK_STREAM)
    # tcpsocket关闭后会有个time_wait(2SML), 在这个时间内被关闭的端口号无法使用, 该设置可解除该限制
    serverSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    localAddr = ('', 7788)
    serverSocket.bind(localAddr)
    serverSocket.listen(5)
    serverSocket.setblocking(False)             # 设置为非阻塞

    while True:
        # 1.检索有没有新的连接过来
        try:
            newCLientInfo = serverSocket.accept()
        except Exception as e:
            pass
        else:
            newCLientInfo[0].setblocking(False)  # newClientInfo是个元组
            g_socketList.append(newCLientInfo)

        needDelClientInfoList = []               # 用来存储需要删除的客户端信息

        # 2. 遍历所有客户端, 并检索有没有接收到数据
        for clientSocket, clientAddr in g_socketList:
            try:
                recvData = clientSocket.recv(1024)
                if len(recvData):                       # recvData的len为0则表示socket关闭
                    print('Client address is:', clientAddr)
                    print('Recieved data is:', recvData)
                else:
                    print('Client is closed')
                    needDelClientInfoList.append((clientSocket, clientAddr))
                    break
            except Exception as e:
                pass

        # 3. 删掉已经关闭的客户端
        for needDelClientInfo in needDelClientInfoList:
            g_socketList.remove(needDelClientInfo)

if  __name__=='__main__':
    print('Hello')
    main()